package cn.com.hhrcw.web;

import cn.com.hhrcw.params.MobileAdminParams;
import cn.com.hhrcw.sms.service.ISysSmsTemplateService;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.time.DateUtils;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.constant.CommonConstant;
import org.jeecg.common.system.api.ISysBaseAPI;
import org.jeecg.common.system.vo.DictModel;
import org.jeecg.common.util.IPUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.ui.ModelMap;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.*;
import java.util.concurrent.TimeUnit;

/**
 * 发送验证码
 *
 * @author lixingxing
 * @since 2020年08月12日16:54:16
 */
@RestController
@RequestMapping("/admin/code")
@Slf4j
@Validated
public class SendController {
    private static final String VAILD_KEY = "create_admin_sms_token_vaild_";
    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    ISysSmsTemplateService sysSmsTemplateService;
    @Value("${jeecg.sms.secret}")
    private String secret;
    @Autowired
    protected ISysBaseAPI sysBaseApi;
    @Value("${spring.profiles.active}")
    private String profiles;
    /**
     * 获取手机验证码
     *
     * @param
     * @return
     */
    @PostMapping("/getMobileCode")
    public Result<?> getCode(@RequestBody MobileAdminParams params, HttpServletRequest request) {
        List<DictModel> dictModels = sysBaseApi.queryDictItemsByCode("SMSCODE_USER_KEY_CODE");
        String token = params.getToken();
        String mobile = params.getMobile();
        String sign = params.getSign();

        String comId="";
        String dayPhone="";
        String dayIp="";
        String hourPhone = "";
        for (DictModel model : dictModels) {
            if ("SMSCODE_USER_CODE".equals(model.getText())){
                comId=model.getValue();
            }
            if ("SMSCODE_USER_DAY_CODE".equals(model.getText())){
                dayPhone=model.getValue();
            }
            if ("SMSCODE_IP_DAY_CODE".equals(model.getText())){
                dayIp=model.getValue();
            }
            if ("SMSCODE_USER_HOUR_CODE".equals(model.getText())){
                hourPhone =model.getValue();
            }
        }


        String s = DigestUtils.md5Hex(token + mobile + secret);
        if (!s.equals(sign)){
            return Result.error("短信token已过期，请重新生成");
        }
        String addr = IPUtils.getIpAddr(request);
        String key= CommonConstant.SMSCODE_USER_CODE+mobile;
        String ipKey= CommonConstant.SMSCODE_IP_DAY_CODE+addr+ DateUtil.format(new Date(),"yyyy-MM-dd");
        Boolean hasKey = redisTemplate.hasKey(key);
        if (hasKey){
            //1分钟之内多次调用限制
            return Result.error("短信验证码操作过于频繁");
        }

        //每小时获取验证码次数
        String keyHour = CommonConstant.SMSCODE_USER_HOUR_CODE + mobile + DateUtil.format(new Date(), "yyyy-MM-dd");
        Integer countHour = (Integer) redisTemplate.opsForValue().get(keyHour);
        log.info("===一小时验证码的次数===="+countHour);
        if (StringUtils.isEmpty(hourPhone)){
            hourPhone="5";
        }
        if(countHour !=null && countHour > Long.valueOf(hourPhone)){
            return Result.error("1小时内短信验证码操作过于频繁");
        }


        //每天获取验证码次数
        String keyDay= CommonConstant.SMSCODE_USER_DAY_CODE+mobile+DateUtil.format(new Date(),"yyyy-MM-dd");
        Integer stock = (Integer)redisTemplate.opsForValue().get(keyDay);
        if (StrUtil.isNotBlank(dayPhone)){
            if (stock != null && stock > Integer.valueOf(dayPhone)){
                return Result.error("短信验证码操作过于频繁");
            }
        }

        Integer ipStock = (Integer)redisTemplate.opsForValue().get(ipKey);
        if (StrUtil.isNotBlank(dayIp)){
            if (ipStock != null && ipStock > Integer.valueOf(dayIp)){
                return Result.error("今天短信验证码操作过于频繁");
            }
        }

        String key1 = VAILD_KEY+mobile;
        if(!redisTemplate.hasKey(key1)){
            //已过期
            Result.error("短信发送权限token已过期，请重新生成");
        }else{
            String orignToken = (String) redisTemplate.opsForValue().get(key1);
            if(!token.equals(orignToken)){
                Result.error("短信发送权限token已过期，请重新生成");
            }
        }
        String[] mobile1=new String[]{mobile};
        boolean b = sysSmsTemplateService.sendSms("admin",mobile1);
        if (b) {
            //当天时间
            Date date = new Date();
            //当天零点
            date = DateUtils.truncate(date, Calendar.DAY_OF_MONTH);
            //第二天零点
            date = DateUtils.addDays(date, +1);

            //一小时过期
            redisTemplate.opsForValue().increment(keyHour, 1);
            redisTemplate.expire(keyHour, 1 , TimeUnit.HOURS);


            redisTemplate.opsForValue().increment(keyDay,1);
            redisTemplate.opsForValue().increment(ipKey,1);
            redisTemplate.expireAt(keyDay, date);
            redisTemplate.expireAt(ipKey, date);
            redisTemplate.opsForValue().set(key,mobile,Long.valueOf(comId),TimeUnit.MINUTES);
            return Result.ok();
        }

        return Result.ok();
    }
    /**
     * 生成发短信令牌
     */
    @RequestMapping(value = "/create_token.thtml", method = RequestMethod.POST)
    @ResponseBody
    public Result createSmsToken(@RequestBody ModelMap requestBody, HttpServletRequest request,
                                 HttpServletResponse response){
        Map<String, Object> ret = new LinkedHashMap<String, Object>();

        String phone = (String) requestBody.get("mobile");
        int eleven = 11;
        if (StringUtils.isBlank(phone)) {
            return Result.error("请输入手机号！");
        } else if (phone.length() != eleven) {
            return Result.error( "请输入正确的手机号！");
        }
        String token = IdUtil.getSnowflake(0,0).nextIdStr();

        //限制IP生成令牌  10秒
        String ip = IPUtils.getIpAddr(request);
        String key = "create_sms_token_limit_"+ip;

        String ipKey="5";
        List<DictModel> dictModels = sysBaseApi.queryDictItemsByCode("SMSCODE_USER_KEY_CODE");
        for (DictModel model : dictModels) {
            if ("CREATE_TOKEN_IP".equals(model.getText())) {
                ipKey = model.getValue();
            }
        }
        //限制加入缓存；
        redisTemplate.opsForValue().set(key,token,Long.valueOf(ipKey), TimeUnit.SECONDS);

        //验证令牌加入缓存
        String key1 = VAILD_KEY+phone;
        redisTemplate.opsForValue().set(key1,token,5,TimeUnit.MINUTES);

        ret.put("token",token);
        return Result.ok(ret);

    }
}
